/*
 * Copyright (C) 2014 Eduardo Pereira Montenegro <epereiramontenegro@gmail.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.googlecode.bambole.util;

/**
 *
 * @author Eduardo Pereira Montenegro <epereiramontenegro@gmail.com>
 */
public class CnpjCpfUtil {

    public static String checkCnpjCpf(String cnpjCpf) {

        cnpjCpf = cnpjCpf.replace('.', ' ');
        cnpjCpf = cnpjCpf.replace('/', ' ');
        cnpjCpf = cnpjCpf.replace('-', ' ');
        cnpjCpf = cnpjCpf.replaceAll(" ", "");

        if (isNumeric(cnpjCpf)) {
            if (checkRepeatedChars(cnpjCpf)) {
                if (checkCNPJ(cnpjCpf).equals("*")) {
                    if (checkCPF(cnpjCpf).equals("*")) {
                        cnpjCpf = "*";
                    } else {
                        cnpjCpf = checkCPF(cnpjCpf);
                    }
                } else {
                    cnpjCpf = checkCNPJ(cnpjCpf);
                }
            } else {
                cnpjCpf = "*";
            }
        } else {
            cnpjCpf = "*";
        }
        return cnpjCpf;
    }

    private static boolean isNumeric(String cnpjCpf) {
        if (cnpjCpf.matches("[0-9]+")) {
            return true;
        }
        return false;
    }

    private static boolean checkRepeatedChars(String cnpjCpf) {

        boolean retVal = false;

        int paramChars = cnpjCpf.length() - 1;
        int repeatedChars = 0;

        for (int i = 1; i <= paramChars; i++) {
            if (cnpjCpf.charAt(i - 1) == cnpjCpf.charAt(i)) {
                repeatedChars++;
            }
        }

        if (paramChars != repeatedChars) {
            retVal = true;
        }

        return retVal;
    }

    private static String checkCPF(String cpf) {
        // Source: http://tribotecnologica.com.br/?p=917
        int iDigito1Aux = 0, iDigito2Aux = 0, iDigitoCPF;
        int iDigito1 = 0, iDigito2 = 0, iRestoDivisao = 0;
        String strDigitoVerificador, strDigitoResultado;

        if (!cpf.substring(0, 1).equals("")) {
            try {
                for (int iCont = 1; iCont < cpf.length() - 1; iCont++) {
                    iDigitoCPF = Integer.valueOf(cpf.substring(iCont - 1, iCont)).intValue();
                    iDigito1Aux = iDigito1Aux + (11 - iCont) * iDigitoCPF;
                    iDigito2Aux = iDigito2Aux + (12 - iCont) * iDigitoCPF;
                }
                iRestoDivisao = (iDigito1Aux % 11);
                if (iRestoDivisao < 2) {
                    iDigito1 = 0;
                } else {
                    iDigito1 = 11 - iRestoDivisao;
                }
                iDigito2Aux += 2 * iDigito1;
                iRestoDivisao = (iDigito2Aux % 11);
                if (iRestoDivisao < 2) {
                    iDigito2 = 0;
                } else {
                    iDigito2 = 11 - iRestoDivisao;
                }
                strDigitoVerificador = cpf.substring(cpf.length() - 2, cpf.length());
                strDigitoResultado = String.valueOf(iDigito1) + String.valueOf(iDigito2);
                if (strDigitoVerificador.equals(strDigitoResultado)) {
                    return cpf.substring(0, 3) + "." + cpf.substring(3, 6) + "." + cpf.substring(6, 9) + "-" + cpf.substring(9, 11);
                } else {
                    return "*";
                }
            } catch (NumberFormatException e) {
                return "*";
            }
        } else {
            return "*";
        }
    }

    private static String checkCNPJ(String cnpj) {
        // Source: http://tribotecnologica.com.br/?p=917
        int iSoma = 0, iDigito;
        char[] chCaracteresCNPJ;
        String strCNPJ_Calculado;

        if (!cnpj.substring(0, 1).equals("")) {
            try {
                strCNPJ_Calculado = cnpj.substring(0, 12);
                if (cnpj.length() != 14) {
                    return "*";
                }
                chCaracteresCNPJ = cnpj.toCharArray();
                for (int i = 0; i < 4; i++) {
                    if ((chCaracteresCNPJ[i] - 48 >= 0) && (chCaracteresCNPJ[i] - 48 <= 9)) {
                        iSoma += (chCaracteresCNPJ[i] - 48) * (6 - (i + 1));
                    }
                }
                for (int i = 0; i < 8; i++) {
                    if ((chCaracteresCNPJ[i + 4] - 48 >= 0) && (chCaracteresCNPJ[i + 4] - 48 <= 9)) {
                        iSoma += (chCaracteresCNPJ[i + 4] - 48) * (10 - (i + 1));
                    }
                }
                iDigito = 11 - (iSoma % 11);
                strCNPJ_Calculado += ((iDigito == 10) || (iDigito == 11)) ? "0" : Integer.toString(iDigito);
                /* Segunda parte */
                iSoma = 0;
                for (int i = 0; i < 5; i++) {
                    if ((chCaracteresCNPJ[i] - 48 >= 0) && (chCaracteresCNPJ[i] - 48 <= 9)) {
                        iSoma += (chCaracteresCNPJ[i] - 48) * (7 - (i + 1));
                    }
                }
                for (int i = 0; i < 8; i++) {
                    if ((chCaracteresCNPJ[i + 5] - 48 >= 0) && (chCaracteresCNPJ[i + 5] - 48 <= 9)) {
                        iSoma += (chCaracteresCNPJ[i + 5] - 48) * (10 - (i + 1));
                    }
                }
                iDigito = 11 - (iSoma % 11);
                strCNPJ_Calculado += ((iDigito == 10) || (iDigito == 11)) ? "0" : Integer.toString(iDigito);
                if (cnpj.equals(strCNPJ_Calculado)) {
                    return cnpj.substring(0, 2) + "." + cnpj.substring(2, 5) + "." + cnpj.substring(5, 8) + "/" + cnpj.substring(8, 12) + "-" + cnpj.substring(12, 14);
                } else {
                    return "*";
                }
            } catch (Exception e) {
                return "*";
            }
        } else {
            return "*";
        }
    }

}
